package com.tron.game.jobs;


import com.alibaba.fastjson.JSONObject;
import com.tron.game.configs.TronConfig;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.tron.trident.abi.FunctionEncoder;
import org.tron.trident.abi.FunctionReturnDecoder;
import org.tron.trident.abi.TypeReference;
import org.tron.trident.abi.datatypes.*;
import org.tron.trident.core.ApiWrapper;
import org.tron.trident.core.exceptions.IllegalException;
import org.tron.trident.core.transaction.TransactionBuilder;
import org.tron.trident.proto.Chain;
import org.tron.trident.proto.Contract;
import org.tron.trident.proto.Response;
import org.tron.trident.utils.Numeric;

import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;

/**
 * 同步用户信息Job
 * @author pan_junbiao
 **/
@DisallowConcurrentExecution

public class CheckJob extends QuartzJobBean
{
    private static final Logger sysLog = LoggerFactory.getLogger(CheckJob.class);
    @Autowired
    TronConfig tronConfig;

    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext)
    {
        //获取JobDetail中传递的参数
       /* String userName = (String) jobExecutionContext.getJobDetail().getJobDataMap().get("userName");
        String blogUrl = (String) jobExecutionContext.getJobDetail().getJobDataMap().get("blogUrl");
        String blogRemark = (String) jobExecutionContext.getJobDetail().getJobDataMap().get("blogRemark");
*/
        //获取当前时间
        Date date = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        //打印信息
        System.out.println("检查数据:当前时间：" + dateFormat.format(date));
        boolean check=CheckGame();
        //System.out.println("检查结果：" +(check?"已到时需要开奖":"未到结束时间"));
        sysLog.error("检查结果：" +(check?"已到时需要开奖":"未到结束时间"));
        if(check)
        {
            String Transaction_Id= PrizeGame();
            sysLog.error("开奖：" + Transaction_Id);
        }else{
            try {
                long over_time = getCurrentRoundInfo();
                long now = getNow();
                long advance_seconds = 2 * 60 * 60;
                sysLog.error("本局结束时间:"+new Date(over_time*1000)+"\r\n"+"现在时间:"+new Date(now*1000));
                if (now + advance_seconds >= over_time) {
                    BuyToken();
                    sysLog.error("自动购买");
                }
            }catch (Exception ex)
            {

            }
        }

        System.out.println("----------------------------------------");
    }
    private  boolean CheckGame()
    {
        ApiWrapper wrapper = null;
        if("nile".equals(tronConfig.getNetwork())) {
            wrapper= ApiWrapper.ofNile(tronConfig.getPrivateKey());
        }else if("shasta".equals(tronConfig.getNetwork())) {
            wrapper= ApiWrapper.ofShasta(tronConfig.getPrivateKey());
        }else {
            wrapper= ApiWrapper.ofMainnet(tronConfig.getPrivateKey(),tronConfig.getApi_key());
        }

        Function buy_token = new Function("checkGameAndPrize", Collections.emptyList(), Arrays.asList(new TypeReference<Bool>() {}));
        Response.TransactionExtention askprice_extension = wrapper.constantCall(tronConfig.getAddress(), tronConfig.getContract_address(), buy_token);
        String checkGameAndPrize_result = Numeric.toHexString(askprice_extension.getConstantResult(0).toByteArray());
        boolean askprice_result1=(boolean) FunctionReturnDecoder.decode(checkGameAndPrize_result, buy_token.getOutputParameters()).get(0).getValue();
        return askprice_result1;

    }

    private String PrizeGame()
    {
        ApiWrapper wrapper = null;
        if("nile".equals(tronConfig.getNetwork())) {
            wrapper= ApiWrapper.ofNile(tronConfig.getPrivateKey());
        }else if("shasta".equals(tronConfig.getNetwork())) {
            wrapper= ApiWrapper.ofShasta(tronConfig.getPrivateKey());
        }else {
            wrapper= ApiWrapper.ofMainnet(tronConfig.getPrivateKey(),tronConfig.getApi_key());
        }
        Function PrizeGame = new Function("PrizeGame",Collections.emptyList(),Arrays.asList(new TypeReference<Bool>() {}));
        String encodedHex = FunctionEncoder.encode(PrizeGame);
        Contract.TriggerSmartContract trigger =
                Contract.TriggerSmartContract.newBuilder()
                        .setOwnerAddress(ApiWrapper.parseAddress(tronConfig.getAddress()))
                        .setContractAddress(ApiWrapper.parseAddress(tronConfig.getContract_address()))
                        .setData(ApiWrapper.parseHex(encodedHex))
                        .build();
        Response.TransactionExtention txnExt = wrapper.blockingStub.triggerContract(trigger);
        TransactionBuilder builder = wrapper.triggerCall(tronConfig.getAddress(), tronConfig.getContract_address(), PrizeGame);
        builder.setTransaction(txnExt.getTransaction());
        builder.setFeeLimit(400000000L);
        Chain.Transaction transaction =builder.build();

        Chain.Transaction signedTxn = wrapper.signTransaction(transaction);
        String ret = wrapper.broadcastTransaction(signedTxn);
        return  ret;
    }

    String BuyToken() {
        ApiWrapper wrapper = null;
        if("nile".equals(tronConfig.getNetwork())) {
            wrapper= ApiWrapper.ofNile(tronConfig.getPrivateKey());
        }else if("shasta".equals(tronConfig.getNetwork())) {
            wrapper= ApiWrapper.ofShasta(tronConfig.getPrivateKey());
        }else {
            wrapper= ApiWrapper.ofMainnet(tronConfig.getPrivateKey(),tronConfig.getApi_key());
        }
        Function askprice = new Function("askprice", Collections.emptyList(), Arrays.asList(new TypeReference<Uint>() {}));
        Response.TransactionExtention askprice_extension = wrapper.constantCall(tronConfig.getAddress(), tronConfig.getContract_address(), askprice);
        String askprice_result = Numeric.toHexString(askprice_extension.getConstantResult(0).toByteArray());
        BigInteger askprice_result1=(BigInteger) FunctionReturnDecoder.decode(askprice_result, askprice.getOutputParameters()).get(0).getValue();


        sysLog.error("自动购买单价:"+askprice_result1);

        Function buy_token = new Function("buy_token",
                Arrays.asList(new Address(tronConfig.getAddress())),Arrays.asList(new TypeReference<Bool>() {}));

        String encodedHex = FunctionEncoder.encode(buy_token);
        Contract.TriggerSmartContract trigger =
                Contract.TriggerSmartContract.newBuilder()
                        .setOwnerAddress(ApiWrapper.parseAddress(tronConfig.getAddress()))
                        .setContractAddress(ApiWrapper.parseAddress(tronConfig.getContract_address()))
                        .setCallValue(askprice_result1.longValue())
                        .setData(ApiWrapper.parseHex(encodedHex))
                        .build();
        Response.TransactionExtention txnExt = wrapper.blockingStub.triggerContract(trigger);


        TransactionBuilder builder = wrapper.triggerCall(tronConfig.getAddress(), tronConfig.getContract_address(), buy_token);
        builder.setTransaction(txnExt.getTransaction());
        builder.setFeeLimit(300000000L);
        Chain.Transaction transaction =builder.build();

        Chain.Transaction signedTxn = wrapper.signTransaction(transaction);
        String ret = wrapper.broadcastTransaction(signedTxn);
        System.out.println("======== Result ========\n" + ret.toString());
        return  "ok";

    }


     long getCurrentRoundInfo() {
        //Nile test net, using a node from Nile official website
        ApiWrapper wrapper = null;
        if("nile".equals(tronConfig.getNetwork())) {
            wrapper= ApiWrapper.ofNile(tronConfig.getPrivateKey());
        }else if("shasta".equals(tronConfig.getNetwork())) {
            wrapper= ApiWrapper.ofShasta(tronConfig.getPrivateKey());
        }else {
            wrapper= ApiWrapper.ofMainnet(tronConfig.getPrivateKey(),tronConfig.getApi_key());
        }

        Function askprice = new Function("getCurrentRoundInfo", Collections.emptyList(), Arrays.asList(
                new TypeReference<Uint>() {},
                new TypeReference<Utf8String>() {},
                new TypeReference<Uint>() {},
                new TypeReference<Uint>() {},
                new TypeReference<Uint>() {},
                new TypeReference<Uint>() {},
                new TypeReference<Uint>() {},
                new TypeReference<Uint>() {},
                new TypeReference<Uint>() {},
                new TypeReference<Uint>() {},
                new TypeReference<Uint>() {},
                new TypeReference<Address>() {},
                new TypeReference<Uint>() {}

        ));
        Response.TransactionExtention askprice_extension = wrapper.constantCall(tronConfig.getAddress(), tronConfig.getContract_address(), askprice);
        String askprice_result = Numeric.toHexString(askprice_extension.getConstantResult(0).toByteArray());
        BigInteger over_time=(BigInteger) FunctionReturnDecoder.decode(askprice_result, askprice.getOutputParameters()).get(5).getValue();
        return over_time.longValue();
    }

    long getNow()
    {
        ApiWrapper wrapper = null;
        if("nile".equals(tronConfig.getNetwork())) {
            wrapper= ApiWrapper.ofNile(tronConfig.getPrivateKey());
        }else if("shasta".equals(tronConfig.getNetwork())) {
            wrapper= ApiWrapper.ofShasta(tronConfig.getPrivateKey());
        }else {
            wrapper= ApiWrapper.ofMainnet(tronConfig.getPrivateKey(),tronConfig.getApi_key());
        }

        Function getNow = new Function("getNow",Collections.emptyList(),Arrays.asList(new TypeReference<Uint>() {}));
        Response.TransactionExtention askprice_extension = wrapper.constantCall(tronConfig.getAddress(), tronConfig.getContract_address(), getNow);
        String askprice_result = Numeric.toHexString(askprice_extension.getConstantResult(0).toByteArray());
        BigInteger now=(BigInteger) FunctionReturnDecoder.decode(askprice_result, getNow.getOutputParameters()).get(0).getValue();
        return  now.longValue();
    }
}
